
package server;

import java.net.Socket;
import java.util.ArrayList;


import nanoxml.XMLElement;
import utils.AbstractConnectionThread;
import utils.IConnection;

import commands.CommandNewUser;
import commands.CommandNewUserError;
import commands.CommandNotifyDBCrashed;
import commands.CommandStatistics;
import commands.CommandUserNotVerified;
import commands.CommandUserVerified;
import commands.Commands;

/**
 * This is the server's connection with the DB
 */
public class ConnectionThreadServerToDB extends AbstractConnectionThread {
	
	private RPSServer server;
	
	public ConnectionThreadServerToDB (Socket dbSocket) {
		super (dbSocket);
		this.server = RPSServer.getInstance();
	}

	/**
	 * Parse the command and perform the required action
	 */
	public void parse (XMLElement command) {
		try {
			if (command.getName().equals(Commands.USER_VERIFIED)) {
				CommandUserVerified commandUserVerify = new CommandUserVerified(command);
				String username = commandUserVerify.getUsername();
				((ConnectionThreadRPSServerToClient)server.getConnections().getConnection(username)).addNewUser(username);
			} 
			else if (command.getName().equals(Commands.USER_NOT_VERIFIED)) {
				CommandUserNotVerified userNotVerified = new CommandUserNotVerified(command);
				String username = userNotVerified.getUsername();
				ConnectionThreadRPSServerToClient conn = (ConnectionThreadRPSServerToClient)server.getConnections().getConnection(username);
				conn.send(command);
			} 
			else if (command.getName().equals(Commands.NEW_USER)) { 
				CommandNewUser userNewUser = new CommandNewUser(command);
				String username = userNewUser.getUsername();
				ConnectionThreadRPSServerToClient conn = (ConnectionThreadRPSServerToClient)server.getConnections().getConnection(username);
				conn.send(command);

			}
			else if (command.getName().equals(Commands.NEW_USER_ERROR)) { 
				CommandNewUserError userNewUserError = new CommandNewUserError(command);
				String username = userNewUserError.getUsername();
				ConnectionThreadRPSServerToClient conn = (ConnectionThreadRPSServerToClient)server.getConnections().getConnection(username);
				conn.send(command);
			}
			
			else if (command.getName().equals(Commands.STATISTICS)) { 
				CommandStatistics statistics = new CommandStatistics(command);
				String username = statistics.getUserName();
				ConnectionThreadRPSServerToClient conn = (ConnectionThreadRPSServerToClient)server.getConnections().getConnection(username);
				conn.send(command);
			}
			
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}

	@Override
	public void handleDisconnection()
	{
		try {
			server.setDbOn(false);
			ArrayList<IConnection> connList = server.getConnections().getConnectionsList();
			for (IConnection conn : connList) {
				((ConnectionThreadRPSServerToClient)conn).send(new CommandNotifyDBCrashed("Database is unavailable. If you are playing a game, the result won't be saved.", "clientPanel"));
			}	
			//closing the old connection
			server.getDBconn().socket.close();
			int dbPort = server.getDbPort();
			String dbHost = server.getDbHost(); 
			
			boolean loop = true;
			//This thread will try to connect to DB until he returns
			while (loop) {
				try {
					Socket dbSocket = new Socket (dbHost, dbPort);  //socket for db
					loop = false;
					server.setDBconn(new ConnectionThreadServerToDB(dbSocket));
					server.setDbOn(true);
					server.getDBconn().start();
					connList = server.getConnections().getConnectionsList();
					for (IConnection conn : connList) {
						((ConnectionThreadRPSServerToClient)conn).send(new CommandNotifyDBCrashed("Database is back on. If you are playing a game, the result will be saved.", "clientPanel"));
					}
				}
				catch (Exception e) { 
					
				}
			}
		}
		catch (Exception e) { 
			e.printStackTrace();
		}
		
	}
}